package com.pyl.admin.system.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.SqlHelper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.pyl.admin.core.enums.ResultEnum;
import com.pyl.admin.core.enums.StatusEnum;
import com.pyl.admin.core.exception.ResultException;
import com.pyl.admin.core.shiro.ShiroUtil;
import com.pyl.admin.system.entity.SysMenu;
import com.pyl.admin.system.entity.SysRoleMenu;
import com.pyl.admin.system.mapper.SysMenuMapper;
import com.pyl.admin.system.mapper.SysRoleMenuMapper;
import com.pyl.admin.system.service.SysMenuService;
import com.pyl.admin.system.validator.MenuForm;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 灵魂贰婶
 * @since 2019-06-28
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

	@Autowired
	private SysMenuMapper sysMenuMapper;

	@Autowired
	private SysRoleMenuMapper sysRoleMenuMapper;

	@Override
	public List<SysMenu> selectMenuList(String query, Integer status) {

		return sysMenuMapper.selectMenuList(query, status);
	}

	@Override
	public List<SysMenu> selectByPid(Long pid, Long notId) {
		List<SysMenu> sysMenus = sysMenuMapper.selectList(new EntityWrapper<SysMenu>().eq("pid", pid).ne("id", notId)
				.eq("status", Integer.valueOf(StatusEnum.OK.getCode())).orderAsc(Arrays.asList("sort")));
		return sysMenus;
	}

	@Override
	public Integer selectSortMax(Long pid) {

		return sysMenuMapper.selectSortMax(pid);
	}

	@Override
	@Transactional
	public boolean updateStatus(StatusEnum statusEnum, List<Long> idList) {

		for (int i = 0; i < idList.size(); i++) {
			SysMenu menu = sysMenuMapper.selectById(idList.get(i));
			// 是否有子项
			List<SysMenu> childMenus = sysMenuMapper.selectList(new EntityWrapper<SysMenu>().eq("pid", menu.getId())
					.eq("status", Integer.valueOf(StatusEnum.OK.getCode())));
			if (CollectionUtil.isNotEmpty(childMenus)) {
				throw new ResultException(ResultEnum.HAVE_CHILD_MENU);
			}

			// 获取兄弟节点
			List<SysMenu> brotherMenu = new ArrayList<SysMenu>();
			brotherMenu = sysMenuMapper
					.selectList(new EntityWrapper<SysMenu>().eq("pid", menu.getPid()).ne("id", menu.getId())
							.eq("status", Integer.valueOf(StatusEnum.OK.getCode())).orderAsc(Arrays.asList("sort")));

			menu.setStatus(Integer.valueOf(statusEnum.getCode()));
			menu.setUpdateBy(ShiroUtil.getSubject().getId());
			menu.setUpdateByName(ShiroUtil.getSubject().getNickname());
			menu.setUpdateDate(new Date());
			// 判断是 启用还是 删除冻结
			if (statusEnum == StatusEnum.OK) {
				brotherMenu.add(menu.getSort() - 1, menu);
			} else if (statusEnum == StatusEnum.FREEZED || statusEnum == StatusEnum.DELETE) {
				// 删除 角色菜单
				sysRoleMenuMapper.delete(new EntityWrapper<SysRoleMenu>().eq("menu_id", menu.getId()));
				sysMenuMapper.updateById(menu);
			}
			// 重新排序
			if (CollectionUtil.isNotEmpty(brotherMenu)) {
				for (int j = 0; j < brotherMenu.size(); j++) {
					SysMenu sysMenu = brotherMenu.get(j);
					sysMenu.setUpdateBy(ShiroUtil.getSubject().getId());
					sysMenu.setUpdateByName(ShiroUtil.getSubject().getNickname());
					sysMenu.setUpdateDate(new Date());
					sysMenu.setSort(j + 1);
					sysMenuMapper.updateById(sysMenu);
				}
			}
		}
		return true;
	}

	@Override
	@Transactional
	public boolean saveOrUpdate(MenuForm menuForm) {
		// 新增
		// 重置父级菜单
		if (menuForm.getPid() != 0) {
			SysMenu pMenu = sysMenuMapper.selectOne(new SysMenu().setId(menuForm.getPid()));
			menuForm.setPids(pMenu.getPids() + ",[" + menuForm.getPid() + "]");
		} else {
			menuForm.setPids("[0]");
		}
		if (menuForm.getId() == null) {
			SysMenu sysMenu = new SysMenu();
			BeanUtil.copyProperties(menuForm, sysMenu, CopyOptions.create().setIgnoreNullValue(true));
			sysMenu.setCreateBy(ShiroUtil.getSubject().getId());
			sysMenu.setCreateByName(ShiroUtil.getSubject().getNickname());
			sysMenu.setCreateDate(new Date());
			sysMenu.setStatus(Integer.valueOf(StatusEnum.OK.getCode()));
			sysMenu.setUpdateBy(ShiroUtil.getSubject().getId());
			sysMenu.setUpdateByName(ShiroUtil.getSubject().getNickname());
			sysMenu.setUpdateDate(new Date());
			// 判断是否重新排序
			List<SysMenu> sysMenus = sysMenuMapper.restOrderby(menuForm.getPid(), menuForm.getSort(), null, null);
			// 后移一位
			if (CollectionUtil.isNotEmpty(sysMenus)) {
				sysMenu.setSort(menuForm.getSort() == 0 ? 1 : menuForm.getSort() + 1);
				for (int i = 0; i < sysMenus.size(); i++) {
					sysMenuMapper.updateById(sysMenus.get(i).setSort(sysMenus.get(i).getSort() + 1));
				}
			} else { // 排在最后面
				Integer sortMax = sysMenuMapper.selectSortMax(menuForm.getPid());
				if (ObjectUtil.isNotNull(sortMax)) {
					sysMenu.setSort(sortMax + 1);
				} else {
					sysMenu.setSort(1);
				}

			}
			return SqlHelper.retBool(sysMenuMapper.insert(sysMenu));

		}

		// 更新
		List<SysMenu> sysMenus = sysMenuMapper
				.selectList(new EntityWrapper<SysMenu>().eq("pid", menuForm.getPid()).ne("id", menuForm.getId())
						.eq("status", Integer.valueOf(StatusEnum.OK.getCode())).orderAsc(Arrays.asList("sort")));

		SysMenu sysMenu = sysMenuMapper.selectById(menuForm.getId());
		BeanUtil.copyProperties(menuForm, sysMenu, CopyOptions.create().setIgnoreNullValue(true));
		sysMenu.setUpdateBy(ShiroUtil.getSubject().getId());
		sysMenu.setUpdateByName(ShiroUtil.getSubject().getNickname());
		sysMenu.setUpdateDate(new Date());
		// 设置排序
		sysMenus.add(menuForm.getSort(), sysMenu);
		for (int i = 0; i < sysMenus.size(); i++) {
			SysMenu menu = sysMenus.get(i);
			menu.setSort(i + 1);
			menu.setUpdateBy(ShiroUtil.getSubject().getId());
			menu.setUpdateByName(ShiroUtil.getSubject().getNickname());
			menu.setUpdateDate(new Date());
			sysMenuMapper.updateById(menu);
		}
		return true;
	}

}
